home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / editors / eedraw / src / ed / eelibs2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-12  |  58.9 KB  |  1,711 lines

  1. /*****************************************************************************
  2. *   Module to handle libraries (second part - drawing and interaction).         *
  3. *                                         *
  4. * Written by:  Gershon Elber            IBM PC Ver 1.0,    Oct. 1989    *
  5. *****************************************************************************/
  6.  
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <conio.h>
  11. #include <string.h>
  12. #include <dos.h>
  13. #include <dir.h>
  14. #include <alloc.h>
  15. #include <time.h>
  16. #include "Program.h"
  17. #include "Director.h"
  18. #include "PriorQue.h"
  19. #include "EELibs.h"
  20. #include "EELibsL.h"
  21. #include "EECreate.h"
  22. #include "EELoad.h"
  23. #include "EEModify.h"
  24. #include "EERedraw.h"
  25. #include "EEString.h"
  26. #include "EELayer.h"
  27. #include "Primary.h"
  28.  
  29. /* Used the hold cursor information for local cursor drawing routines. */
  30. static DrawLibItemStruct *CrsrDrawLibItem;
  31. static LibraryEntryStruct *CrsrLibEntry;
  32. static IntrCursorShapeStruct Cursor = {
  33.     INTR_CURSOR_ARROW, 0, 0, 0, 0, FALSE, NULL, FALSE
  34. };
  35.  
  36. static char *TransformStrs[] =
  37. {
  38.     "PlaceIt",
  39.     "",
  40.     "RotateR",
  41.     "RotateL",
  42.     "MirrorX",
  43.     "MirrorY",
  44. };
  45. #define TRANS_MENU_SIZE (sizeof(TransformStrs) / sizeof(char *))
  46.  
  47. static IntrPopUpMenuStruct
  48.     *TransPopUpMenu = NULL;
  49.  
  50. static void DrawLibPartAux(LibraryEntryStruct *Entry, int PartX, int PartY,
  51.     int TransMat[2][2], int Multi, int DrawMode, int Mode);
  52. static void PushNetListItem(NetListStruct **NetList,
  53.                 int MapX1, int MapY1, int MapX2, int MapY2,
  54.                 char *PartName, char *ChipName, char *PinName,
  55.                 int PinNum);
  56. static char *LookUpPinText(char *Pins, int PinNum);
  57. static void MapAngles(int *Angle1, int *Angle2, int TransMat[2][2]);
  58. static void ViewOneLibrary(LibraryStruct *Lib);
  59. static LibraryEntryStruct *FindLibPart(char *Name);
  60. static void DrawingEntryCursor(int x, int y);
  61.  
  62. /*****************************************************************************
  63. * Routine to view library(ies) content.                         *
  64. *****************************************************************************/
  65. void ViewLibrary(void)
  66. {
  67.     int i, NumOfLibs = NumOfLibraries();
  68.     char **Names;
  69.     LibraryStruct *Lib;
  70.  
  71.     Cursor.CursorType = INTR_CURSOR_ARROW;
  72.  
  73.     if (NumOfLibs == 0) {
  74.     IntrQueryContinue("No libraries are loaded", EEPopUpFrameColor,
  75.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  76.                           EEWindowsFrameWidth, &Cursor,
  77.                           INTR_WNDW_PLACE_CENTER);
  78.  
  79.     return;
  80.     }
  81.     Names = (char **) MyMalloc(sizeof(char *) * NumOfLibs);
  82.     for (i = 0, Lib = LibraryList; Lib != NULL; Lib = Lib -> Pnext, i++) {
  83.     Names[i] = Lib -> Name;
  84.     }
  85.     do {
  86.     i = IntrQueryList("View Libs", (char **) Names, 0, NumOfLibs,
  87.               EEListNumDisplayed, EEPopUpFrameColor,
  88.                           EEPopUpBackColor, EEPopUpForeColor,
  89.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  90.                           INTR_WNDW_PLACE_CENTER);
  91.     if (i >= 0) {
  92.             IntrWndwPop(EERootWindowID, TRUE, FALSE);
  93.  
  94.         for (Lib = LibraryList; i > 0; i--, Lib = Lib -> Pnext);
  95.         ViewOneLibrary(Lib);
  96.  
  97.             IntrWndwPush(EERootWindowID, TRUE);
  98.     }
  99.     }
  100.     while (i >= 0);
  101.  
  102.     MyFree((VoidPtr) Names);
  103. }
  104.  
  105. /*****************************************************************************
  106. * Routine to draw the given part at given position, transformed/mirror as    *
  107. * specified, and in the given drawing mode. Only this one is visible...         *
  108. *****************************************************************************/
  109. void DrawLibPart(DrawLibItemStruct *DrawLibItem, int DrawMode, int Color)
  110. {
  111.     LibraryEntryStruct *Entry;
  112.     char Line[LINE_LEN];
  113.  
  114.     GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
  115.  
  116.     Cursor.CursorType = INTR_CURSOR_ARROW;
  117.  
  118.     if ((Entry = FindLibPart(DrawLibItem -> ChipName)) == NULL) {
  119.     sprintf(Line, "Failed to find part \"%s\" in library",
  120.                         DrawLibItem -> ChipName);
  121.     IntrQueryContinue(Line, EEPopUpFrameColor,
  122.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  123.                           EEWindowsFrameWidth, &Cursor,
  124.                           INTR_WNDW_PLACE_CENTER);
  125.     return;
  126.     }
  127.     if(Color==EE_ERASE_COLOR)
  128.         DrawLibPartAux(Entry,
  129.            DrawLibItem -> PosX,
  130.            DrawLibItem -> PosY,
  131.            DrawLibItem -> Transform,
  132.            DrawLibItem -> Multi,
  133.            DrawMode,
  134.            0);
  135.     else
  136.         DrawLibPartAux(Entry,
  137.            DrawLibItem -> PosX,
  138.            DrawLibItem -> PosY,
  139.            DrawLibItem -> Transform,
  140.            DrawLibItem -> Multi,
  141.            DrawMode,
  142.            1);
  143.  
  144.     if (Entry -> DrawName &&
  145.     DrawLibItem -> ChipNameOrient != TEXT_ORIENT_NON){
  146.     if((ReturnLayerMode(LAYER_DEVICE) & 0x03) && Color!=EE_ERASE_COLOR)
  147.         GRSetColor(ReturnLayerColor(LAYER_DEVICE));
  148.     else
  149.         GRSetColor(EE_ERASE_COLOR);
  150.  
  151.     PutTextInfo(DrawLibItem -> ChipNameOrient,
  152.             DrawLibItem -> ChipNameX,
  153.             DrawLibItem -> ChipNameY,
  154.             1,
  155.              DrawLibItem -> ChipName); 
  156.         
  157.     
  158.     }
  159.     if (DrawLibItem -> PartNameOrient != TEXT_ORIENT_NON){
  160.     if((ReturnLayerMode(LAYER_REFDES) & 0x03) && Color!=EE_ERASE_COLOR)
  161.         GRSetColor(ReturnLayerColor(LAYER_REFDES));
  162.     else
  163.         GRSetColor(EE_ERASE_COLOR);
  164.      
  165.     PutTextInfo(DrawLibItem -> PartNameOrient,
  166.             DrawLibItem -> PartNameX,
  167.             DrawLibItem -> PartNameY,
  168.             1,
  169.             DrawLibItem -> PartName); 
  170.     
  171.     }
  172. }
  173.  
  174. /*****************************************************************************
  175. * Routine to clear the given part at given position,                         *
  176. *****************************************************************************/
  177. void DrawLibPartClear(DrawLibItemStruct *DrawLibItem, int DrawMode)
  178. {
  179.     LibraryEntryStruct *Entry;
  180.     
  181.     char Line[LINE_LEN];
  182.  
  183.     GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
  184.  
  185.     Cursor.CursorType = INTR_CURSOR_ARROW;
  186.  
  187.     if ((Entry = FindLibPart(DrawLibItem -> ChipName)) == NULL) {
  188.     sprintf(Line, "Failed to find part \"%s\" in library",
  189.                         DrawLibItem -> ChipName);
  190.     IntrQueryContinue(Line, EEPopUpFrameColor,
  191.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  192.                           EEWindowsFrameWidth, &Cursor,
  193.                           INTR_WNDW_PLACE_CENTER);
  194.     return;
  195.     }
  196.     
  197.    DrawLibPartAux(Entry,
  198.        DrawLibItem -> PosX,
  199.        DrawLibItem -> PosY,
  200.        DrawLibItem -> Transform,
  201.        DrawLibItem -> Multi,
  202.        DrawMode,
  203.        0);
  204.  
  205.  
  206.     if (Entry -> DrawName &&
  207.     DrawLibItem -> ChipNameOrient != TEXT_ORIENT_NON){
  208.     GRSetColor(EE_ERASE_COLOR);
  209.     PutTextInfo(DrawLibItem -> ChipNameOrient,
  210.             DrawLibItem -> ChipNameX,
  211.             DrawLibItem -> ChipNameY,
  212.             1,
  213.             DrawLibItem -> ChipName);
  214.     
  215.     }
  216.     if (DrawLibItem -> PartNameOrient != TEXT_ORIENT_NON){
  217.     GRSetColor(EE_ERASE_COLOR);
  218.     PutTextInfo(DrawLibItem -> PartNameOrient,
  219.             DrawLibItem -> PartNameX,
  220.             DrawLibItem -> PartNameY,
  221.             1,
  222.             DrawLibItem -> PartName);
  223.     
  224.     }
  225. }
  226. /*****************************************************************************
  227. * Routine to find a part in one of the libraries given its name.         *
  228. *****************************************************************************/
  229. static LibraryEntryStruct *FindLibPart(char *Name)
  230. {
  231.     LibraryEntryStruct *Entry, DummyEntry;
  232.     LibraryStruct
  233.     *Lib = LibraryList;
  234.  
  235.     DummyEntry.Pins = NULL;            /* Used only to call PQFind. */
  236.     DummyEntry.Drawings = NULL;
  237.     DummyEntry.Multi = NULL;
  238.     strcpy(DummyEntry.Name, Name);
  239.  
  240.     PQCompFunc((PQCompFuncType) LibraryEntryCompare);
  241.  
  242.     while (Lib) {
  243.     if ((Entry = PQFind(Lib -> Entries, &DummyEntry)) != NULL)
  244.         return Entry;
  245.  
  246.     Lib = Lib -> Pnext;
  247.     }
  248.     return NULL;
  249. }
  250.  
  251. /*****************************************************************************
  252. * Routine to draw the given part at given position, transformed/mirror as    *
  253. * specified, and in the given drawing mode.                     *
  254. *****************************************************************************/
  255. static void DrawLibPartAux(LibraryEntryStruct *Entry, int PartX, int PartY,
  256.     int TransMat[2][2], int Multi, int DrawMode, int Mode)
  257. /* Mode 0=EE_ERASE_COLOR, Mode 1=LAYER_COLOR */
  258. {
  259.     int i, x1, y1, x2, y2, IsMulti, *NextPinMulti, NextPinNum, t1, t2,
  260.     y, MapX1, MapY1, MapX2, MapY2, PinWidth, *Poly;
  261.     char Line[LINE_LEN], *NextPinText;
  262.     LibraryDrawEntryStruct *DEntry;
  263.  
  264.     /* GRSetFillStyle(GR_SOLID_FILL, Color); */
  265.     GRSetWriteMode(DrawMode);
  266.     
  267.     IsMulti = Entry -> NumOfUnits > 0;
  268.     if (IsMulti) {
  269.     /* Make NextMulti point on next pin number in multi array: */
  270.     NextPinMulti = &Entry -> Multi[Entry -> PinsPerUnit * --Multi];
  271.  
  272.     NextPinText = NULL;
  273.     }
  274.     else {
  275.     NextPinNum = 1;
  276.     NextPinMulti = NULL;
  277.  
  278.     /* Make a copy of all pin text info so we can use strtok routine on: */
  279.     strncpy(Line, Entry -> Pins, LINE_LEN - 1);
  280.     NextPinText = strtok(Line, PIN_SEPERATOR);
  281.     }
  282.  
  283.     if (Entry -> Drawings != NULL) {
  284.     DEntry = Entry -> Drawings;
  285.     while (DEntry != NULL) {
  286.         switch (DEntry -> DrawType) {
  287.         case ARC_DRAW_TYPE:
  288.             
  289.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))             break;
  290.             else if(Mode==0)
  291.             GRSetColor(EE_ERASE_COLOR);
  292.             else
  293.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  294.             t1 = DEntry -> U.Arc.t1;
  295.             t2 = DEntry -> U.Arc.t2;
  296.             MapAngles(&t1, &t2, TransMat);
  297.             GRArc(PartX + TransMat[0][0] * DEntry -> U.Arc.x +
  298.                   TransMat[0][1] * DEntry -> U.Arc.y,
  299.               PartY + TransMat[1][0] * DEntry -> U.Arc.x +
  300.                   TransMat[1][1] * DEntry -> U.Arc.y,
  301.               t1,
  302.               t2,
  303.               DEntry -> U.Arc.r);
  304.             break;
  305.         case CIRCLE_DRAW_TYPE:
  306.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))
  307.  
  308.             break;
  309.             else if(Mode==0)
  310.             GRSetColor(EE_ERASE_COLOR);
  311.             else
  312.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  313.             GRCircle(PartX + TransMat[0][0] * DEntry -> U.Circ.x +
  314.                      TransMat[0][1] * DEntry -> U.Circ.y,
  315.                  PartY + TransMat[1][0] * DEntry -> U.Circ.x +
  316.                      TransMat[1][1] * DEntry -> U.Circ.y,
  317.                  DEntry -> U.Circ.r);
  318.             break;
  319.         case TEXT_DRAW_TYPE:
  320.             
  321.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))
  322.  
  323.             break;
  324.             else if(Mode==0)
  325.             GRSetColor(EE_ERASE_COLOR);
  326.             else
  327.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  328.             /* The text orientation may need to be flipped if the    */
  329.             /* transformation matrix cuases xy axes to be flipped.   */
  330.             t1 = (TransMat[0][0] == 0) ^ (DEntry -> U.Text.Horiz != 0);
  331.             x1 = PartX + TransMat[0][0] * DEntry -> U.Text.x
  332.                    + TransMat[0][1] * DEntry -> U.Text.y;
  333.             y1 = PartY + TransMat[1][0] * DEntry -> U.Text.x
  334.                    + TransMat[1][1] * DEntry -> U.Text.y;
  335.             PutTextInfo(t1 ? GR_HORIZ_DIR : GR_VERT_DIR, x1, y1, 1,
  336.                 DEntry -> U.Text.Text);
  337.             break;
  338.         case SQUARE_DRAW_TYPE:
  339.             
  340.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))
  341.  
  342.             break;
  343.             else if(Mode==0)
  344.             GRSetColor(EE_ERASE_COLOR);
  345.             else
  346.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  347.             x1 = PartX + TransMat[0][0] * DEntry -> U.Sqr.x1
  348.                    + TransMat[0][1] * DEntry -> U.Sqr.y1;
  349.             y1 = PartY + TransMat[1][0] * DEntry -> U.Sqr.x1
  350.                    + TransMat[1][1] * DEntry -> U.Sqr.y1;
  351.             x2 = PartX + TransMat[0][0] * DEntry -> U.Sqr.x2
  352.                    + TransMat[0][1] * DEntry -> U.Sqr.y2;
  353.             y2 = PartY + TransMat[1][0] * DEntry -> U.Sqr.x2
  354.                    + TransMat[1][1] * DEntry -> U.Sqr.y2;
  355.             GRMoveTo(x1, y1);
  356.             GRLineTo(x1, y2);
  357.             GRLineTo(x2, y2);
  358.             GRLineTo(x2, y1);
  359.             GRLineTo(x1, y1);
  360.             break;
  361.         case LINE_DRAW_TYPE:
  362.             
  363.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))             break;
  364.             else if(Mode==0)
  365.             GRSetColor(EE_ERASE_COLOR);
  366.             else
  367.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  368.             x1 = PartX + TransMat[0][0] * DEntry -> U.Line.x1
  369.                    + TransMat[0][1] * DEntry -> U.Line.y1;
  370.             y1 = PartY + TransMat[1][0] * DEntry -> U.Line.x1
  371.                    + TransMat[1][1] * DEntry -> U.Line.y1;
  372.             x2 = PartX + TransMat[0][0] * DEntry -> U.Line.x2
  373.                    + TransMat[0][1] * DEntry -> U.Line.y2;
  374.             y2 = PartY + TransMat[1][0] * DEntry -> U.Line.x2
  375.                    + TransMat[1][1] * DEntry -> U.Line.y2;
  376.             if (DEntry -> U.Line.Invert) {
  377.             MapX1 = SIGN(x2 - x1);
  378.             MapY1 = SIGN(y2 - y1);
  379.             GRCircle(MapX1 * INVERT_PIN_RADIUS + x1,
  380.                  MapY1 * INVERT_PIN_RADIUS + y1,
  381.                  INVERT_PIN_RADIUS);
  382.             GRMoveTo(MapX1 * INVERT_PIN_RADIUS * 2 + x1,
  383.                  MapY1 * INVERT_PIN_RADIUS * 2 + y1);
  384.             GRLineTo(x2, y2);
  385.             }
  386.             else {
  387.             GRMoveTo(x1, y1);
  388.             GRLineTo(x2, y2);
  389.             }
  390.             
  391.             if(Mode==0)
  392.             GRSetColor(EE_ERASE_COLOR);
  393.             else
  394.             GRSetColor(ReturnLayerColor(LAYER_PIN));
  395.             if(ReturnLayerMode(LAYER_PIN))
  396.                 GRCircle(x2,y2,3);
  397.             
  398.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))             break;
  399.             else if(Mode==0)
  400.             GRSetColor(EE_ERASE_COLOR);
  401.             else
  402.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  403.             if (IsMulti) {
  404.             PutLineTextInfo(x1, y1, x2, y2,
  405.                 LookUpPinText(Entry -> Pins, *NextPinMulti),
  406.                 *NextPinMulti,
  407.                 Entry -> TextInside,
  408.                 Entry -> DrawNums,Mode);
  409.             NextPinMulti++;
  410.             }
  411.             else {
  412.             PutLineTextInfo(x1, y1, x2, y2,
  413.                 NextPinText,
  414.                 NextPinNum,
  415.                 Entry -> TextInside,
  416.                 Entry -> DrawNums,Mode);
  417.             NextPinText = strtok(NULL, PIN_SEPERATOR);
  418.             NextPinNum++;
  419.             }
  420.             break;
  421.         case POLYLINE_DRAW_TYPE:
  422.             
  423.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))
  424.  
  425.             break;
  426.             else if(Mode==0)
  427.             GRSetColor(EE_ERASE_COLOR);
  428.             else
  429.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  430.             Poly = (int *) MyMalloc(sizeof(int) * 2 *
  431.                             DEntry -> U.Poly.n);
  432.             for (i = 0; i < DEntry -> U.Poly.n; i++) {
  433.             Poly[i * 2] = PartX +
  434.                 TransMat[0][0] * DEntry -> U.Poly.PolyList[i * 2] +
  435.                 TransMat[0][1] * DEntry -> U.Poly.PolyList[i * 2 + 1];
  436.             Poly[i * 2 + 1] = PartY +
  437.                 TransMat[1][0] * DEntry -> U.Poly.PolyList[i * 2] +
  438.                 TransMat[1][1] * DEntry -> U.Poly.PolyList[i * 2 + 1];
  439.             }
  440.         if(Mode==1)
  441.                GRSetFillStyle(GR_SOLID_FILL,
  442.              ReturnLayerColor(DEntry->Layer));
  443.         else
  444.             GRSetFillStyle(GR_SOLID_FILL,EE_ERASE_COLOR);
  445.             GRPoly(DEntry -> U.Poly.n, Poly, DEntry -> U.Poly.Fill);
  446.             MyFree((VoidPtr) Poly);
  447.             break;
  448.         }
  449.         DEntry = DEntry -> Pnext;
  450.     }
  451.     }
  452.     else {          /* NULL Drawing - draw simple a box with all pins: */
  453.     y1 = Entry -> TextInside ? PIN_WIDTH * Entry -> NumOfPins / 4 :
  454.                    PIN_WIDTH * Entry -> NumOfPins / 2;
  455.     x1 = Entry -> TextInside ? (int) (y1 * CHIP_BOX_ASPECT_TI) :
  456.                    (int) (y1 * CHIP_BOX_ASPECT_TO);
  457.     /* But make sure we can still print somethings inside... */
  458.     if (x1 < DRAW_TEXT_WIDTH * 12) x1 = DRAW_TEXT_WIDTH * 12;
  459.     x2 = x1 / 2;
  460.     y2 = y1 / 2;
  461.     x1 = -x2;
  462.     y1 = -y2;
  463.     PinWidth = Entry -> TextInside ? PIN_WIDTH / 2 : PIN_WIDTH;
  464.  
  465. /* Set the primary Layer Colours by guess work! */
  466.     GRSetColor(LAYER_DEVICE);
  467.     GRMoveTo(PartX + TransMat[0][0] * x1 + TransMat[0][1] * y1,
  468.          PartY + TransMat[1][0] * x1 + TransMat[1][1] * y1);
  469.     GRLineTo(PartX + TransMat[0][0] * x1 + TransMat[0][1] * y2,
  470.          PartY + TransMat[1][0] * x1 + TransMat[1][1] * y2);
  471.     GRLineTo(PartX + TransMat[0][0] * x2 + TransMat[0][1] * y2,
  472.          PartY + TransMat[1][0] * x2 + TransMat[1][1] * y2);
  473.     GRLineTo(PartX + TransMat[0][0] * x2 + TransMat[0][1] * y1,
  474.          PartY + TransMat[1][0] * x2 + TransMat[1][1] * y1);
  475.     GRLineTo(PartX + TransMat[0][0] * x1 + TransMat[0][1] * y1,
  476.          PartY + TransMat[1][0] * x1 + TransMat[1][1] * y1);
  477.     for (i = 0; i < Entry -> NumOfPins / 2; i++) {
  478.         y = y2 - PinWidth / 2 - i * PinWidth;
  479.         MapX1 = PartX + TransMat[0][0] * x1 + TransMat[0][1] * y;
  480.         MapY1 = PartY + TransMat[1][0] * x1 + TransMat[1][1] * y;
  481.         MapX2 = PartX + TransMat[0][0] * (x1 - PIN_LENGTH) + TransMat[0][1] * y;
  482.         MapY2 = PartY + TransMat[1][0] * (x1 - PIN_LENGTH) + TransMat[1][1] * y;
  483.         GRMoveTo(MapX1, MapY1);
  484.         GRLineTo(MapX2, MapY2);
  485.             if(Mode==0)
  486.             GRSetColor(EE_ERASE_COLOR);
  487.             else
  488.             GRSetColor(ReturnLayerColor(LAYER_PIN));
  489.             if(ReturnLayerMode(LAYER_PIN))
  490.                 GRCircle(x2,y2,3);
  491.             
  492.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))             break;
  493.             else if(Mode==0)
  494.             GRSetColor(EE_ERASE_COLOR);
  495.             else
  496.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  497.         if (IsMulti) {
  498.         GRSetColor(LAYER_PINNUM);
  499.         PutLineTextInfo(MapX1, MapY1, MapX2, MapY2,
  500.             LookUpPinText(Entry -> Pins, *NextPinMulti),
  501.             *NextPinMulti,
  502.             Entry -> TextInside,
  503.             Entry -> DrawNums,Mode);
  504.         NextPinMulti++;
  505.         }
  506.         else {
  507.         GRSetColor(LAYER_PINNUM);
  508.         PutLineTextInfo(MapX1, MapY1, MapX2, MapY2,
  509.             NextPinText,
  510.             NextPinNum,
  511.             Entry -> TextInside,
  512.             Entry -> DrawNums,Mode);
  513.         NextPinText = strtok(NULL, PIN_SEPERATOR);
  514.         NextPinNum++;
  515.         }
  516.     }
  517.     for (i = Entry -> NumOfPins / 2 + 1; i <= Entry -> NumOfPins; i++) {
  518.         y = y1 + PinWidth / 2 + (i - Entry -> NumOfPins / 2 - 1) *
  519.                                 PinWidth;
  520.         MapX1 = PartX + TransMat[0][0] * x2 + TransMat[0][1] * y;
  521.         MapY1 = PartY + TransMat[1][0] * x2 + TransMat[1][1] * y;
  522.         MapX2 = PartX + TransMat[0][0] * (x2 + PIN_LENGTH) + TransMat[0][1] * y;
  523.         MapY2 = PartY + TransMat[1][0] * (x2 + PIN_LENGTH) + TransMat[1][1] * y;
  524. /* Set the primary Layer Colours by guess work! */
  525.     GRSetColor(LAYER_DEVICE);
  526.         GRMoveTo(MapX1, MapY1);
  527.         GRLineTo(MapX2, MapY2);
  528.             if(Mode==0)
  529.             GRSetColor(EE_ERASE_COLOR);
  530.             else
  531.             GRSetColor(ReturnLayerColor(LAYER_PIN));
  532.             if(ReturnLayerMode(LAYER_PIN))
  533.                 GRCircle(x2,y2,3);
  534.             
  535.             if((!(ReturnLayerMode(DEntry -> Layer) & 0x03)) & (Mode==1))             break;
  536.             else if(Mode==0)
  537.             GRSetColor(EE_ERASE_COLOR);
  538.             else
  539.             GRSetColor(ReturnLayerColor(DEntry -> Layer));
  540.         if (IsMulti) {
  541.         GRSetColor(LAYER_PINNUM);
  542.         PutLineTextInfo(MapX1, MapY1, MapX2, MapY2,
  543.             LookUpPinText(Entry -> Pins, *NextPinMulti),
  544.             *NextPinMulti,
  545.             Entry -> TextInside,
  546.             Entry -> DrawNums,Mode);
  547.         NextPinMulti++;
  548.         }
  549.         else {
  550.         GRSetColor(LAYER_PINNAM);
  551.         PutLineTextInfo(MapX1, MapY1, MapX2, MapY2,
  552.             NextPinText,
  553.             NextPinNum,
  554.             Entry -> TextInside,
  555.             Entry -> DrawNums,Mode);
  556.         NextPinText = strtok(NULL, PIN_SEPERATOR);
  557.         NextPinNum++;
  558.         }
  559.     }
  560.     }
  561. }
  562.  
  563. /*****************************************************************************
  564. * Routine to find the closest connection point of the library item to the    *
  565. * given point and set ClosestX/Y to it.                         *
  566. * As the only connections are defined via LINE definition only those are     *
  567. * tested. More than that - only the second point entry of LINE is tested as  *
  568. * the first one is the connection to the object itself.                 *
  569. *****************************************************************************/
  570. void SnapLibItemPoint(int OrigX, int OrigY, int *ClosestX, int *ClosestY,
  571.                         DrawLibItemStruct *DrawLibItem)
  572. {
  573.     int i, TempX, TempY, TempY1, TransMat[2][2], PartX, PartY, *Points,
  574.     x1, y1, x2, y2, PinWidth;
  575.     unsigned int Dist;
  576.     char Line[LINE_LEN_SHORT];
  577.     LibraryEntryStruct *Entry;
  578.     LibraryDrawEntryStruct *DEntry;
  579.  
  580.     GEN_COPY(TransMat, DrawLibItem -> Transform, sizeof(int) * 4);
  581.     PartX = DrawLibItem -> PosX;
  582.     PartY = DrawLibItem -> PosY;
  583.     Dist = ((unsigned int) ABS(*ClosestX - OrigX)) +
  584.        ((unsigned int) ABS(*ClosestY - OrigY));
  585.  
  586.     Cursor.CursorType = INTR_CURSOR_ARROW;
  587.  
  588.     if ((Entry = FindLibPart(DrawLibItem -> ChipName)) == NULL) {
  589.     sprintf(Line, "Failed to find part \"%s\" in library",
  590.                         DrawLibItem -> PartName);
  591.     IntrQueryContinue(Line, EEPopUpFrameColor,
  592.               EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  593.               EEWindowsFrameWidth, &Cursor,
  594.                           INTR_WNDW_PLACE_CENTER);
  595.     return;
  596.     }
  597.  
  598.     if (Entry -> Drawings != NULL) {
  599.     DEntry = Entry -> Drawings;
  600.     while (DEntry != NULL) {
  601.         switch (DEntry -> DrawType) {
  602.         case LINE_DRAW_TYPE:
  603.             TempX = PartX + TransMat[0][0] * DEntry -> U.Line.x1
  604.                     + TransMat[0][1] * DEntry -> U.Line.y1;
  605.             TempY = PartY + TransMat[1][0] * DEntry -> U.Line.x1
  606.                     + TransMat[1][1] * DEntry -> U.Line.y1;
  607.             if (((unsigned int) ABS(TempX - OrigX)) +
  608.             ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  609.             *ClosestX = TempX;
  610.             *ClosestY = TempY;
  611.             Dist = ((unsigned int) ABS(TempX - OrigX)) +
  612.                    ((unsigned int) ABS(TempY - OrigY));
  613.             }
  614.             TempX = PartX + TransMat[0][0] * DEntry -> U.Line.x2
  615.                     + TransMat[0][1] * DEntry -> U.Line.y2;
  616.             TempY = PartY + TransMat[1][0] * DEntry -> U.Line.x2
  617.                     + TransMat[1][1] * DEntry -> U.Line.y2;
  618.             if (((unsigned int) ABS(TempX - OrigX)) +
  619.             ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  620.             *ClosestX = TempX;
  621.             *ClosestY = TempY;
  622.             Dist = ((unsigned int) ABS(TempX - OrigX)) +
  623.                    ((unsigned int) ABS(TempY - OrigY));
  624.             }
  625.             break;
  626.         case SQUARE_DRAW_TYPE:
  627.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x1
  628.                     + TransMat[0][1] * DEntry -> U.Sqr.y1;
  629.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x1
  630.                     + TransMat[1][1] * DEntry -> U.Sqr.y1;
  631.             if (((unsigned int) ABS(TempX - OrigX)) +
  632.             ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  633.             *ClosestX = TempX;
  634.             *ClosestY = TempY;
  635.             Dist = ((unsigned int) ABS(TempX - OrigX)) +
  636.                    ((unsigned int) ABS(TempY - OrigY));
  637.             }
  638.  
  639.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x2
  640.                     + TransMat[0][1] * DEntry -> U.Sqr.y2;
  641.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x2
  642.                     + TransMat[1][1] * DEntry -> U.Sqr.y2;
  643.             if (((unsigned int) ABS(TempX - OrigX)) +
  644.             ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  645.             *ClosestX = TempX;
  646.             *ClosestY = TempY;
  647.             Dist = ((unsigned int) ABS(TempX - OrigX)) +
  648.                    ((unsigned int) ABS(TempY - OrigY));
  649.             }
  650.  
  651.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x2
  652.                     + TransMat[0][1] * DEntry -> U.Sqr.y1;
  653.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x2
  654.                     + TransMat[1][1] * DEntry -> U.Sqr.y1;
  655.             if (((unsigned int) ABS(TempX - OrigX)) +
  656.             ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  657.             *ClosestX = TempX;
  658.             *ClosestY = TempY;
  659.             Dist = ((unsigned int) ABS(TempX - OrigX)) +
  660.                    ((unsigned int) ABS(TempY - OrigY));
  661.             }
  662.  
  663.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x1
  664.                     + TransMat[0][1] * DEntry -> U.Sqr.y2;
  665.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x1
  666.                     + TransMat[1][1] * DEntry -> U.Sqr.y2;
  667.             if (((unsigned int) ABS(TempX - OrigX)) +
  668.             ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  669.             *ClosestX = TempX;
  670.             *ClosestY = TempY;
  671.             Dist = ((unsigned int) ABS(TempX - OrigX)) +
  672.                    ((unsigned int) ABS(TempY - OrigY));
  673.             }
  674.             break;
  675.         case POLYLINE_DRAW_TYPE:
  676.             Points = DEntry -> U.Poly.PolyList;
  677.             for (i = 0; i < DEntry -> U.Poly.n; i++) {
  678.             TempX = PartX + TransMat[0][0] * Points[i * 2]
  679.                       + TransMat[0][1] * Points[i * 2 + 1];
  680.             TempY = PartY + TransMat[1][0] * Points[i * 2]
  681.                       + TransMat[1][1] * Points[i * 2 + 1];
  682.  
  683.             if (((unsigned int) ABS(TempX - OrigX)) +
  684.                 ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  685.                 *ClosestX = TempX;
  686.                 *ClosestY = TempY;
  687.                 Dist = ((unsigned int) ABS(TempX - OrigX)) +
  688.                    ((unsigned int) ABS(TempY - OrigY));
  689.             }
  690.             }
  691.             break;
  692.         case ARC_DRAW_TYPE:
  693.         case CIRCLE_DRAW_TYPE:
  694.         case TEXT_DRAW_TYPE:
  695.             break;
  696.         }
  697.         DEntry = DEntry -> Pnext;
  698.     }
  699.     }
  700.     else {                      /* Simple a box with all pins: */
  701.     y1 = Entry -> TextInside ? PIN_WIDTH * Entry -> NumOfPins / 4 :
  702.                    PIN_WIDTH * Entry -> NumOfPins / 2;
  703.     x1 = Entry -> TextInside ? (int) (y1 * CHIP_BOX_ASPECT_TI) :
  704.                    (int) (y1 * CHIP_BOX_ASPECT_TO);
  705.     /* But make sure we can still print somethings inside... */
  706.     if (x1 < DRAW_TEXT_WIDTH * 12) x1 = DRAW_TEXT_WIDTH * 12;
  707.     x2 = x1 / 2;
  708.     y2 = y1 / 2;
  709.     x1 = -x2;
  710.     y1 = -y2;
  711.     PinWidth = Entry -> TextInside ? PIN_WIDTH / 2 : PIN_WIDTH;
  712.  
  713.     for (i = 0; i < Entry -> NumOfPins / 2; i++) {
  714.         TempY1 = y2 - PinWidth / 2 - i * PinWidth;
  715.         TempX = PartX + TransMat[0][0] * (x1 - PIN_LENGTH) +
  716.                 TransMat[0][1] * TempY1;
  717.         TempY = PartY + TransMat[1][0] * (x1 - PIN_LENGTH) +
  718.                 TransMat[1][1] * TempY1;
  719.         if (((unsigned int) ABS(TempX - OrigX)) +
  720.         ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  721.         *ClosestX = TempX;
  722.         *ClosestY = TempY;
  723.         Dist = ((unsigned int) ABS(TempX - OrigX)) +
  724.                ((unsigned int) ABS(TempY - OrigY));
  725.         }
  726.     }
  727.     for (i = Entry -> NumOfPins / 2 + 1; i <= Entry -> NumOfPins; i++) {
  728.         TempY1 = y1 + PinWidth / 2 + (i - Entry -> NumOfPins / 2 - 1) *
  729.                                 PinWidth;
  730.         TempX = PartX + TransMat[0][0] * (x2 + PIN_LENGTH) +
  731.                 TransMat[0][1] * TempY1;
  732.         TempY = PartY + TransMat[1][0] * (x2 + PIN_LENGTH) +
  733.                 TransMat[1][1] * TempY1;
  734.         if (((unsigned int) ABS(TempX - OrigX)) +
  735.         ((unsigned int) ABS(TempY - OrigY)) < Dist) {
  736.         *ClosestX = TempX;
  737.         *ClosestY = TempY;
  738.         Dist = ((unsigned int) ABS(TempX - OrigX)) +
  739.                ((unsigned int) ABS(TempY - OrigY));
  740.         }
  741.     }
  742.     }
  743. }
  744.  
  745. /*****************************************************************************
  746. * Routine to find all pins that have connection to the line from x1/y1 to    *
  747. * x2/y2 in Library item provided. Only terminals (LINE_DRAW_TYPE) are tested.*
  748. *****************************************************************************/
  749. NetListStruct *FindLibItemNetList(int lx1, int ly1, int lx2, int ly2,
  750.                   BooleanType l1Bus,
  751.                   DrawGenericStruct *Phead,
  752.                   DrawLibItemStruct *DrawLibItem)
  753. {
  754.     int i, j, IsMulti, Multi, *NextPinMulti, TransMat[2][2], PartX, PartY,
  755.     NextPinNum, PinWidth, y, x1, y1, x2, y2, MapX1, MapY1, MapX2, MapY2;
  756.     char *p, *NextPinText, Line[LINE_LEN];
  757.     LibraryEntryStruct *Entry;
  758.     LibraryDrawEntryStruct *DEntry;
  759.     NetListStruct
  760.     *NetList = NULL;
  761.  
  762.     GEN_COPY(TransMat, DrawLibItem -> Transform, sizeof(int) * 4);
  763.     PartX = DrawLibItem -> PosX;
  764.     PartY = DrawLibItem -> PosY;
  765.     Multi = DrawLibItem -> Multi;
  766.  
  767.     if ((Entry = FindLibPart(DrawLibItem -> ChipName)) == NULL) {
  768.     sprintf(Line, "Failed to find part \"%s\" in library",
  769.                         DrawLibItem -> PartName);
  770.     IntrQueryContinue(Line, EEPopUpFrameColor,
  771.               EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  772.               EEWindowsFrameWidth, &Cursor,
  773.               INTR_WNDW_PLACE_CENTER);
  774.     return NULL;
  775.     }
  776.  
  777.     IsMulti = Entry -> NumOfUnits > 0;
  778.     if (IsMulti) {
  779.     /* Make NextMulti point on next pin number in multi array: */
  780.     NextPinMulti = &Entry -> Multi[Entry -> PinsPerUnit * --Multi];
  781.  
  782.     NextPinText = NULL;
  783.     }
  784.     else {
  785.     NextPinNum = 1;
  786.     NextPinMulti = NULL;
  787.  
  788.     /* Make a copy of all pin text info so we can use strtok routine on: */
  789.     strncpy(Line, Entry -> Pins, LINE_LEN - 1);
  790.     NextPinText = strtok(Line, PIN_SEPERATOR);
  791.     }
  792.  
  793.     if (Entry -> Drawings != NULL) {
  794.     DEntry = Entry -> Drawings;
  795.     while (DEntry != NULL) {
  796.         switch (DEntry -> DrawType) {
  797.         case LINE_DRAW_TYPE:
  798.             x1 = PartX + TransMat[0][0] * DEntry -> U.Line.x1
  799.                    + TransMat[0][1] * DEntry -> U.Line.y1;
  800.             y1 = PartY + TransMat[1][0] * DEntry -> U.Line.x1
  801.                    + TransMat[1][1] * DEntry -> U.Line.y1;
  802.             x2 = PartX + TransMat[0][0] * DEntry -> U.Line.x2
  803.                    + TransMat[0][1] * DEntry -> U.Line.y2;
  804.             y2 = PartY + TransMat[1][0] * DEntry -> U.Line.x2
  805.                    + TransMat[1][1] * DEntry -> U.Line.y2;
  806.             if (IsMulti) {
  807.             p = LookUpPinText(Entry -> Pins, j = *NextPinMulti);
  808.             NextPinMulti++;
  809.             }
  810.             else {
  811.             p = NextPinText;
  812.             NextPinText = strtok(NULL, PIN_SEPERATOR);
  813.             j = NextPinNum++;
  814.             }
  815.  
  816.             if (LinesIntersect(lx1, ly1, lx2, ly2, x1, y1, x2, y2,
  817.                                l1Bus, FALSE, Phead))
  818.             PushNetListItem(&NetList, x1, y1, x2, y2,
  819.                     DrawLibItem -> PartName,
  820.                     DrawLibItem -> ChipName, p, j);
  821.             break;
  822.         }
  823.         DEntry = DEntry -> Pnext;
  824.     }
  825.     }
  826.     else {                      /* Simple a box with all pins: */
  827.     PinWidth = Entry -> TextInside ? PIN_WIDTH / 2 : PIN_WIDTH;
  828.     y1 = Entry -> TextInside ? PIN_WIDTH * Entry -> NumOfPins / 4 :
  829.                    PIN_WIDTH * Entry -> NumOfPins / 2;
  830.     x1 = Entry -> TextInside ? (int) (y1 * CHIP_BOX_ASPECT_TI) :
  831.                    (int) (y1 * CHIP_BOX_ASPECT_TO);
  832.     /* But make sure we can still print somethings inside... */
  833.     if (x1 < DRAW_TEXT_WIDTH * 12) x1 = DRAW_TEXT_WIDTH * 12;
  834.     x2 = x1 / 2;
  835.     y2 = y1 / 2;
  836.     x1 = -x2;
  837.     y1 = -y2;
  838.  
  839.     for (i = 0; i < Entry -> NumOfPins / 2; i++) {
  840.         y = y2 - PinWidth / 2 - i * PinWidth;
  841.         MapX1 = PartX + TransMat[0][0] * x1 + TransMat[0][1] * y;
  842.         MapY1 = PartY + TransMat[1][0] * x1 + TransMat[1][1] * y;
  843.         MapX2 = PartX + TransMat[0][0] * (x1 - PIN_LENGTH) + TransMat[0][1] * y;
  844.         MapY2 = PartY + TransMat[1][0] * (x1 - PIN_LENGTH) + TransMat[1][1] * y;
  845.         if (IsMulti) {
  846.         p = LookUpPinText(Entry -> Pins, j = *NextPinMulti);
  847.         NextPinMulti++;
  848.         }
  849.         else {
  850.         p = NextPinText;
  851.         NextPinText = strtok(NULL, PIN_SEPERATOR);
  852.         j = NextPinNum++;
  853.         }
  854.  
  855.         if (LinesIntersect(lx1, ly1, lx2, ly2,
  856.                    MapX1, MapY1, MapX2, MapY2,
  857.                    l1Bus, FALSE, Phead))
  858.         PushNetListItem(&NetList, MapX1, MapY1, MapX2, MapY2,
  859.                 DrawLibItem -> PartName,
  860.                 DrawLibItem -> ChipName, p, j);
  861.     }
  862.     for (i = Entry -> NumOfPins / 2 + 1; i <= Entry -> NumOfPins; i++) {
  863.         y = y1 + PinWidth / 2 + (i - Entry -> NumOfPins / 2 - 1) *
  864.                                 PinWidth;
  865.         MapX1 = PartX + TransMat[0][0] * x2 + TransMat[0][1] * y;
  866.         MapY1 = PartY + TransMat[1][0] * x2 + TransMat[1][1] * y;
  867.         MapX2 = PartX + TransMat[0][0] * (x2 + PIN_LENGTH) + TransMat[0][1] * y;
  868.         MapY2 = PartY + TransMat[1][0] * (x2 + PIN_LENGTH) + TransMat[1][1] * y;
  869.         if (IsMulti) {
  870.         p = LookUpPinText(Entry -> Pins, *NextPinMulti);
  871.         NextPinMulti++;
  872.         }
  873.         else {
  874.         p = NextPinText;
  875.         NextPinText = strtok(NULL, PIN_SEPERATOR);
  876.         NextPinNum++;
  877.         }
  878.         if (LinesIntersect(lx1, ly1, lx2, ly2,
  879.                    MapX1, MapY1, MapX2, MapY2,
  880.                    l1Bus, FALSE, Phead))
  881.         PushNetListItem(&NetList, MapX1, MapY1, MapX2, MapY2,
  882.                 DrawLibItem -> PartName,
  883.                 DrawLibItem -> ChipName, p, j);
  884.     }
  885.     }
  886.  
  887.     return NetList;
  888. }
  889.  
  890. /*****************************************************************************
  891. * Routine to push one net list item on the NetList list.             *
  892. * In addition the library item L line is drawn in current color/mode.        *
  893. *****************************************************************************/
  894. static void PushNetListItem(NetListStruct **NetList,
  895.                 int MapX1, int MapY1, int MapX2, int MapY2,
  896.                 char *PartName, char *ChipName, char *PinName,
  897.                 int PinNum)
  898. {
  899.     struct NetListStruct *NetListItem = (NetListStruct *)
  900.                           MyMalloc(sizeof(NetListStruct));
  901.  
  902.     if (ChipName == NULL) ChipName = "";
  903.     if (PartName == NULL) PartName = "";
  904.     if (PinName == NULL) PinName = "";
  905.  
  906.     if (ChipName[0] == '~') ChipName = &ChipName[1];
  907.     if (PartName[0] == '~') PartName = &PartName[1];
  908.     if (PinName[0] == '~') PinName = &PinName[1];
  909.  
  910.     sprintf(NetListItem -> Pin, "%s %s %s (Pin %d)",
  911.         ChipName, PartName, PinName, PinNum);
  912.  
  913.     NetListItem -> Pnext = *NetList;
  914.     *NetList = NetListItem;
  915.  
  916.     GRMoveTo(MapX1, MapY1);
  917.     GRLineTo(MapX2, MapY2);
  918. }
  919.  
  920. /*****************************************************************************
  921. * Routine to test if the given library item has non empty intersection with  *
  922. * the given box defined by x1/y1 and x2/y2 (x1 < x2, y1 < y2) and return     *
  923. * TRUE if so. Used to pick objects in a given box.                 *
  924. *****************************************************************************/
  925. BooleanType LibItemInBox(int x1, int y1, int x2, int y2,
  926.                         DrawLibItemStruct *DrawLibItem)
  927. {
  928.     int i, TempX, TempY, TempY1, TransMat[2][2], PartX, PartY, *Points,
  929.     xt1, yt1, xt2, yt2, PinWidth;
  930.     char Line[LINE_LEN_SHORT];
  931.     LibraryEntryStruct *Entry;
  932.     LibraryDrawEntryStruct *DEntry;
  933.  
  934.     GEN_COPY(TransMat, DrawLibItem -> Transform, sizeof(int) * 4);
  935.     PartX = DrawLibItem -> PosX;
  936.     PartY = DrawLibItem -> PosY;
  937.  
  938.     Cursor.CursorType = INTR_CURSOR_ARROW;
  939.  
  940.     if ((Entry = FindLibPart(DrawLibItem -> ChipName)) == NULL) {
  941.     sprintf(Line, "Failed to find part \"%s\" in library",
  942.                         DrawLibItem -> PartName);
  943.     IntrQueryContinue(Line, EEPopUpFrameColor,
  944.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  945.                           EEWindowsFrameWidth, &Cursor,
  946.                           INTR_WNDW_PLACE_CENTER);
  947.     return FALSE;
  948.     }
  949.  
  950.     if (Entry -> Drawings != NULL) {
  951.     DEntry = Entry -> Drawings;
  952.     while (DEntry != NULL) {
  953.         switch (DEntry -> DrawType) {
  954.         case LINE_DRAW_TYPE:
  955.             TempX = PartX + TransMat[0][0] * DEntry -> U.Line.x1
  956.                     + TransMat[0][1] * DEntry -> U.Line.y1;
  957.             TempY = PartY + TransMat[1][0] * DEntry -> U.Line.x1
  958.                     + TransMat[1][1] * DEntry -> U.Line.y1;
  959.             if (TempX >= x1 && TempX <= x2 &&
  960.             TempY >= y1 && TempY <= y2) return TRUE;
  961.  
  962.             TempX = PartX + TransMat[0][0] * DEntry -> U.Line.x2
  963.                     + TransMat[0][1] * DEntry -> U.Line.y2;
  964.             TempY = PartY + TransMat[1][0] * DEntry -> U.Line.x2
  965.                     + TransMat[1][1] * DEntry -> U.Line.y2;
  966.             if (TempX >= x1 && TempX <= x2 &&
  967.             TempY >= y1 && TempY <= y2) return TRUE;
  968.             break;
  969.         case SQUARE_DRAW_TYPE:
  970.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x1
  971.                     + TransMat[0][1] * DEntry -> U.Sqr.y1;
  972.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x1
  973.                     + TransMat[1][1] * DEntry -> U.Sqr.y1;
  974.             if (TempX >= x1 && TempX <= x2 &&
  975.             TempY >= y1 && TempY <= y2) return TRUE;
  976.  
  977.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x2
  978.                     + TransMat[0][1] * DEntry -> U.Sqr.y2;
  979.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x2
  980.                     + TransMat[1][1] * DEntry -> U.Sqr.y2;
  981.             if (TempX >= x1 && TempX <= x2 &&
  982.             TempY >= y1 && TempY <= y2) return TRUE;
  983.  
  984.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x2
  985.                     + TransMat[0][1] * DEntry -> U.Sqr.y1;
  986.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x2
  987.                     + TransMat[1][1] * DEntry -> U.Sqr.y1;
  988.             if (TempX >= x1 && TempX <= x2 &&
  989.             TempY >= y1 && TempY <= y2) return TRUE;
  990.  
  991.             TempX = PartX + TransMat[0][0] * DEntry -> U.Sqr.x1
  992.                     + TransMat[0][1] * DEntry -> U.Sqr.y2;
  993.             TempY = PartY + TransMat[1][0] * DEntry -> U.Sqr.x1
  994.                     + TransMat[1][1] * DEntry -> U.Sqr.y2;
  995.             if (TempX >= x1 && TempX <= x2 &&
  996.             TempY >= y1 && TempY <= y2) return TRUE;
  997.             break;
  998.         case POLYLINE_DRAW_TYPE:
  999.             Points = DEntry -> U.Poly.PolyList;
  1000.             for (i = 0; i < DEntry -> U.Poly.n; i++) {
  1001.             TempX = PartX + TransMat[0][0] * Points[i * 2]
  1002.                       + TransMat[0][1] * Points[i * 2 + 1];
  1003.             TempY = PartY + TransMat[1][0] * Points[i * 2]
  1004.                       + TransMat[1][1] * Points[i * 2 + 1];
  1005.             if (TempX >= x1 && TempX <= x2 &&
  1006.                 TempY >= y1 && TempY <= y2) return TRUE;
  1007.  
  1008.             }
  1009.             break;
  1010.         case ARC_DRAW_TYPE:
  1011.         case CIRCLE_DRAW_TYPE:
  1012.         case TEXT_DRAW_TYPE:
  1013.             break;
  1014.         }
  1015.         DEntry = DEntry -> Pnext;
  1016.     }
  1017.     }
  1018.     else {                      /* Simple a box with all pins: */
  1019.     yt1 = Entry -> TextInside ? PIN_WIDTH * Entry -> NumOfPins / 4 :
  1020.                     PIN_WIDTH * Entry -> NumOfPins / 2;
  1021.     xt1 = Entry -> TextInside ? (int) (yt1 * CHIP_BOX_ASPECT_TI) :
  1022.                     (int) (yt1 * CHIP_BOX_ASPECT_TO);
  1023.         /* But make sure we can still print somethings inside... */
  1024.     if (xt1 < DRAW_TEXT_WIDTH * 12) xt1 = DRAW_TEXT_WIDTH * 12;
  1025.     xt2 = xt1 / 2;
  1026.     yt2 = yt1 / 2;
  1027.     xt1 = -xt2;
  1028.     yt1 = -yt2;
  1029.     PinWidth = Entry -> TextInside ? PIN_WIDTH / 2 : PIN_WIDTH;
  1030.  
  1031.     for (i = 0; i < Entry -> NumOfPins / 2; i++) {
  1032.         TempY1 = yt2 - PinWidth / 2 - i * PinWidth;
  1033.         TempX = PartX + TransMat[0][0] * (xt1 - PIN_LENGTH) +
  1034.                 TransMat[0][1] * TempY1;
  1035.         TempY = PartY + TransMat[1][0] * (xt1 - PIN_LENGTH) +
  1036.                 TransMat[1][1] * TempY1;
  1037.         if (TempX >= x1 && TempX <= x2 &&
  1038.         TempY >= y1 && TempY <= y2) return TRUE;
  1039.     }
  1040.     for (i = Entry -> NumOfPins / 2 + 1; i <= Entry -> NumOfPins; i++) {
  1041.         TempY1 = yt1 + PinWidth / 2 + (i - Entry -> NumOfPins / 2 - 1) *
  1042.                                 PinWidth;
  1043.         TempX = PartX + TransMat[0][0] * (xt2 + PIN_LENGTH) +
  1044.                 TransMat[0][1] * TempY1;
  1045.         TempY = PartY + TransMat[1][0] * (xt2 + PIN_LENGTH) +
  1046.                 TransMat[1][1] * TempY1;
  1047.         if (TempX >= x1 && TempX <= x2 &&
  1048.         TempY >= y1 && TempY <= y2) return TRUE;
  1049.     }
  1050.     }
  1051.  
  1052.     return FALSE;
  1053. }
  1054.  
  1055. /*****************************************************************************
  1056. * Given the Pins string and PinNum returns NULL terminated string of that    *
  1057. * pin allocated statically.                             *
  1058. *****************************************************************************/
  1059. static char *LookUpPinText(char *Pins, int PinNum)
  1060. {
  1061.     static char Pin[MAX_PIN_INFO];
  1062.     int i,
  1063.         Count = 1;
  1064.  
  1065.     while (*Pins && Count != PinNum) {
  1066.     if (*Pins++ == PIN_SEPERATOR[0]) Count++;
  1067.     }
  1068.  
  1069.     if (*Pins) {
  1070.     i = 0;
  1071.     while (i < MAX_PIN_INFO - 1 && *Pins != PIN_SEPERATOR[0] && *Pins != 0)
  1072.         Pin[i++] = *Pins++;
  1073.     Pin[i] = 0;
  1074.     return i > 0 ? Pin : NULL;
  1075.     }
  1076.     else {
  1077.     return NULL;
  1078.     }
  1079. }
  1080.  
  1081. /*****************************************************************************
  1082. * Routine to rotate the given angular direction by the given Transformation. *
  1083. * Input (and output) angles must be as follows:                     *
  1084. * Angle1 in [0..360], Angle2 > Angle1 in [0..720]. Arc is assumed to be less *
  1085. * than 180 degrees.                                 *
  1086. * Algorithm:                                     *
  1087. * Map the angles to a point on the unit circle which is mapped using the     *
  1088. * transform (only mirror and rotate so it remains on the unit circle) to     *
  1089. * a new point which is used to detect new angle.                 *
  1090. *****************************************************************************/
  1091. static void MapAngles(int *Angle1, int *Angle2, int TransMat[2][2])
  1092. {
  1093.     int Angle;
  1094.     RealType x, y, t;
  1095.  
  1096.     x = cos(*Angle1 * M_PI / 180.0);
  1097.     y = sin(*Angle1 * M_PI / 180.0);
  1098.     t = x * TransMat[0][0] + y * TransMat[0][1];
  1099.     y = x * TransMat[1][0] + y * TransMat[1][1];
  1100.     x = t;
  1101.     *Angle1 = (int) (atan2(y, x) * 180.0 / M_PI + 0.5);
  1102.  
  1103.     x = cos(*Angle2 * M_PI / 180.0);
  1104.     y = sin(*Angle2 * M_PI / 180.0);
  1105.     t = x * TransMat[0][0] + y * TransMat[0][1];
  1106.     y = x * TransMat[1][0] + y * TransMat[1][1];
  1107.     x = t;
  1108.     *Angle2 = (int) (atan2(y, x) * 180.0 / M_PI + 0.5);
  1109.  
  1110.     NORMALIZE_ANGLE(*Angle1);
  1111.     NORMALIZE_ANGLE(*Angle2);
  1112.     if (*Angle2 < *Angle1) *Angle2 += 360;
  1113.  
  1114.     if (*Angle2 - *Angle1 > 180) {         /* Need to swap the two angles. */
  1115.     Angle = (*Angle1);
  1116.     *Angle1 = (*Angle2);
  1117.     *Angle2 = Angle;
  1118.  
  1119.     NORMALIZE_ANGLE(*Angle1);
  1120.     NORMALIZE_ANGLE(*Angle2);
  1121.     if (*Angle2 < *Angle1) *Angle2 += 360;
  1122.     }
  1123.  
  1124.     *Angle1 -= 1;    /* As the angles loaded are decreased by 1 when loaded. */
  1125.     *Angle2 += 1;
  1126. }
  1127.  
  1128. /*****************************************************************************
  1129. * Routine to view one selected library content.                     *
  1130. *****************************************************************************/
  1131. static void ViewOneLibrary(LibraryStruct *Lib)
  1132. {
  1133.     int i, x, y, TransMat[2][2],
  1134.     NumOfParts = Lib -> NumOfParts;
  1135.     char **PartNames;
  1136.     LibraryEntryStruct *LibEntry, *Entry,
  1137.     *LastEntry = NULL;
  1138.  
  1139.     Cursor.CursorType = INTR_CURSOR_ARROW;
  1140.  
  1141.     if (NumOfParts == 0) {
  1142.     IntrQueryContinue("Library is empty!", EEPopUpFrameColor,
  1143.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  1144.                           EEWindowsFrameWidth, &Cursor,
  1145.                           INTR_WNDW_PLACE_CENTER);
  1146.     return;
  1147.     }
  1148.     PartNames = (char **) MyMalloc(sizeof(char *) * NumOfParts);
  1149.  
  1150.     PQCompFunc((PQCompFuncType) LibraryEntryCompare);
  1151.     LibEntry = (LibraryEntryStruct *) PQFirst(&Lib -> Entries, FALSE);
  1152.     PartNames[0] = LibEntry -> Name;
  1153.     for (i = 1; i < NumOfParts; i++) {
  1154.     if ((LibEntry = (LibraryEntryStruct *)
  1155.           PQNext(Lib -> Entries, LibEntry, NULL)) == NULL) {
  1156.         /* Number of parts does not match what we really have. This is   */
  1157.         /* wierd but we will try to do what we can:                 */
  1158.         NumOfParts = i - 1;
  1159.         break;
  1160.     }
  1161.     PartNames[i] = LibEntry -> Name;
  1162.     }
  1163.  
  1164.     x = GRInvMapX(GRScreenMaxX * 3 / 4);     /* Where to put the drawn part: */
  1165.     y = GRInvMapY(GRScreenMaxY / 2);
  1166.     TransMat[0][0] = 1.0;
  1167.     TransMat[1][1] = -1.0;
  1168.     TransMat[1][0] = TransMat[0][1] = 0.0;
  1169.  
  1170.     do {
  1171.     i = IntrQueryList("ViewLib", (char **) PartNames, 0, NumOfParts,
  1172.               EEListNumDisplayed, EEPopUpFrameColor,
  1173.                           EEPopUpBackColor, EEPopUpForeColor,
  1174.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  1175.                           INTR_WNDW_PLACE_LEFT);
  1176.  
  1177.     if (LastEntry) {                  /* Erase old part. */
  1178.         DrawLibPartAux(LastEntry, x, y, TransMat, 1, GR_COPY_PUT,
  1179.                           IntrAllocColor(EERootWndwBackColor,
  1180.                                 INTR_INTENSITY_HIGH ));
  1181.         LastEntry = NULL;
  1182.     }
  1183.  
  1184.     if (i >= 0) {                       /* Draw new part. */
  1185.         Entry = FindLibPart(PartNames[i]);
  1186.         DrawLibPartAux(Entry, x, y, TransMat,
  1187.                                1, GR_COPY_PUT, 1);
  1188.         LastEntry = Entry;
  1189.     }
  1190.     }
  1191.     while (i >= 0);
  1192.  
  1193.     MyFree((VoidPtr) PartNames);
  1194. }
  1195.  
  1196. /*****************************************************************************
  1197. * Routine to handle lib part creation. Return NULL if fails.             *
  1198. *****************************************************************************/
  1199. DrawGenericStruct *LibCreateNewPart(void)
  1200. {
  1201.     static char Name[LINE_LEN_SHORT] = { 0 };
  1202.     int x, y, TransMat[2][2], TempMat[2][2], TempR, Multi, PopPosition;
  1203.     BooleanType Transform,
  1204.     Quit = FALSE;
  1205.     char Line[LINE_LEN], Buffer[LINE_LEN_SHORT];
  1206.     char L2[LINE_LEN];
  1207.     LibraryEntryStruct *Entry;
  1208.     DrawLibItemStruct *DrawLibItem;
  1209.  
  1210.     IntrQueryLine("Library part name:", Name, LINE_LEN_SHORT - 1,
  1211.               EEPopUpFrameColor, EEPopUpBackColor, EEPopUpForeColor,
  1212.                   EEWindowsFrameWidth, INTR_WNDW_PLACE_CENTER);
  1213.  
  1214.     if (strlen(Name) == 0) return NULL;
  1215.     strupr(Name);
  1216.  
  1217.     Cursor.CursorType = INTR_CURSOR_ARROW;
  1218.  
  1219.     if ((Entry = FindLibPart(Name)) == NULL) {
  1220.     sprintf(Line, "Failed to find part \"%s\" in library", Name);
  1221.     IntrQueryContinue(Line, EEPopUpFrameColor,
  1222.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  1223.                           EEWindowsFrameWidth, &Cursor, INTR_WNDW_PLACE_CENTER);
  1224.     return NULL;
  1225.     }
  1226.  
  1227.     if (Entry -> NumOfUnits > 1) {
  1228.     do {
  1229.         sprintf(Line, "This chip has %d multiple units. Which one (1-%d):",
  1230.                 Entry -> NumOfUnits, Entry -> NumOfUnits);
  1231.         strcpy(Buffer, "1");
  1232.         IntrQueryLine(Line, Buffer, LINE_LEN_SHORT - 1,
  1233.                       EEPopUpFrameColor, EEPopUpBackColor,
  1234.                           EEPopUpForeColor, EEWindowsFrameWidth,
  1235.                           INTR_WNDW_PLACE_CENTER);
  1236.     }
  1237.     while (sscanf(Buffer, "%d", &Multi) != 1 ||
  1238.            Multi <= 0 ||
  1239.            Multi > Entry -> NumOfUnits);
  1240.     }
  1241.     else
  1242.     Multi = 1;
  1243.  
  1244.     x = GRScreenMaxX * 3 / 4;             /* Where to put the drawn part: */
  1245.     y = GRScreenMaxY / 2;
  1246.  
  1247.     /* Prepare the transformation information: */
  1248.     TransMat[0][0] = 1.0;
  1249.     TransMat[1][1] = -1.0;
  1250.     TransMat[1][0] = TransMat[0][1] = 0.0;
  1251.  
  1252.     if (TransPopUpMenu == NULL) TransPopUpMenu =
  1253.         IntrPopUpMenuCreate("Transform", (char **) TransformStrs, 0,
  1254.                     TRANS_MENU_SIZE, EEPopUpFrameColor,
  1255.                             EEPopUpBackColor, EEPopUpForeColor,
  1256.                             EEPopUpXorColor, EEWindowsFrameWidth, &Cursor);
  1257.  
  1258.     do {
  1259.  
  1260.     DrawLibPartAux(Entry, GRInvMapX(x), GRInvMapY(y), TransMat,
  1261.                Multi, GR_COPY_PUT, 1);
  1262.  
  1263.     if (!IntrPopUpMenu(TransPopUpMenu, INTR_WNDW_PLACE_LEFT)) {
  1264.             /* If abort key. */
  1265.  
  1266.         DrawLibPartAux(Entry, GRInvMapX(x), GRInvMapY(y), TransMat,
  1267.                    Multi, GR_COPY_PUT, 0);
  1268.  
  1269.         return NULL;
  1270.     }
  1271.  
  1272.     DrawLibPartAux(Entry, GRInvMapX(x), GRInvMapY(y), TransMat,
  1273.                Multi, GR_COPY_PUT, 0);
  1274.  
  1275.     Transform = TRUE;
  1276.     if (!Quit) switch (TransPopUpMenu -> SelectedIndex) {
  1277.         case 0:
  1278.         Quit = TRUE;
  1279.         break;
  1280.         case 2:
  1281.         TempMat[0][0] = TempMat[1][1] = 0.0;
  1282.         TempMat[0][1] = 1.0;
  1283.         TempMat[1][0] = -1.0;
  1284.         break;
  1285.         case 3:
  1286.         TempMat[0][0] = TempMat[1][1] = 0.0;
  1287.         TempMat[0][1] = -1.0;
  1288.         TempMat[1][0] = 1.0;
  1289.         break;
  1290.         case 4:
  1291.         TempMat[0][0] = -1.0;
  1292.         TempMat[1][1] = 1.0;
  1293.         TempMat[0][1] = TempMat[1][0] = 0.0;
  1294.         break;
  1295.         case 5:
  1296.         TempMat[0][0] = 1.0;
  1297.         TempMat[1][1] = -1.0;
  1298.         TempMat[0][1] = TempMat[1][0] = 0.0;
  1299.         break;
  1300.         default:
  1301.         Transform = FALSE;
  1302.         break;
  1303.     }
  1304.     if (!Quit && Transform) {
  1305.         TempR = TransMat[0][0] * TempMat[0][0] +
  1306.                         TransMat[0][1] * TempMat[1][0];
  1307.         TransMat[0][1] = TransMat[0][0] * TempMat[0][1] +
  1308.                         TransMat[0][1] * TempMat[1][1];
  1309.         TransMat[0][0] = TempR;
  1310.         TempR = TransMat[1][0] * TempMat[0][0] +
  1311.                         TransMat[1][1] * TempMat[1][0];
  1312.         TransMat[1][1] = TransMat[1][0] * TempMat[0][1] +
  1313.                         TransMat[1][1] * TempMat[1][1];
  1314.         TransMat[1][0] = TempR;
  1315.     }
  1316.     }
  1317.     while (!Quit);
  1318.  
  1319.     /* Allocate the structure to be returned, and fill it with information   */
  1320.     /* we know so far.                                 */
  1321.     DrawLibItem = (DrawLibItemStruct *) MyMalloc(sizeof(DrawLibItemStruct));
  1322.     DrawLibItem -> Pnext = NULL;
  1323.     DrawLibItem -> StructType = DRAW_LIB_ITEM_STRUCT_TYPE;
  1324.     DrawLibItem -> Multi = Multi;
  1325.     DrawLibItem -> PartNameOrient =
  1326.     DrawLibItem -> ChipNameOrient = TEXT_ORIENT_NON;
  1327.     DrawLibItem -> ChipName = strdup(Name);
  1328.     DrawLibItem -> PartName = NULL;
  1329.     DrawLibItem -> PosX = DrawLibItem -> PosY = -20000;
  1330.     GEN_COPY(DrawLibItem -> Transform, TransMat, sizeof(int) * 4);
  1331.  
  1332.     PutCursorInActiveWindow();
  1333.     IntrSetIdleFunction(AutoPanActiveWindow);
  1334.  
  1335.     /* Place the part in its exact place and update part and chip names. */
  1336.     if (!PlaceLibItem(DrawLibItem)) {
  1337.     MyFree((VoidPtr) DrawLibItem);
  1338.         IntrSetIdleFunction(NULL);
  1339.     return NULL;
  1340.     }
  1341.  
  1342.     IntrSetIdleFunction(NULL);
  1343.  
  1344.     /* Update the BBox knowledge: */
  1345.     DrawLibItem -> BBoxMinX = DrawLibItem -> PosX + Entry -> BBoxMinX;
  1346.     DrawLibItem -> BBoxMaxX = DrawLibItem -> PosX + Entry -> BBoxMaxX;
  1347.     DrawLibItem -> BBoxMinY = DrawLibItem -> PosY + Entry -> BBoxMinY;
  1348.     DrawLibItem -> BBoxMaxY = DrawLibItem -> PosY + Entry -> BBoxMaxY;
  1349.  
  1350.     DrawLibPart(DrawLibItem, GR_COPY_PUT, 1);
  1351.  
  1352.     /* Put the structure in the global object list, so automatic panning     */
  1353.     /* will draw it as well. It will be removed from EEDrawList before exit. */
  1354.     DrawLibItem -> Pnext = EEActiveWindow -> EEDrawList;
  1355.     EEActiveWindow -> EEDrawList = (DrawGenericStruct *) DrawLibItem;
  1356.  
  1357.     PopPosition = GRMapX(DrawLibItem -> PosX) < GRScreenMaxX / 2 ?
  1358.                             INTR_WNDW_PLACE_RIGHT :
  1359.                             INTR_WNDW_PLACE_LEFT;
  1360.  
  1361.     Cursor.CursorType = INTR_CURSOR_ARROW;
  1362.  
  1363.     if (Entry -> DrawName &&
  1364.     IntrQueryYesNo("Display chip name?", EEPopUpFrameColor,
  1365.                EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  1366.                        EEWindowsFrameWidth, &Cursor, PopPosition)) {
  1367.     DrawLibItem -> ChipNameX = DrawLibItem -> PosX;
  1368.     DrawLibItem -> ChipNameY = DrawLibItem -> PosY;
  1369.     if (!PlaceString(DrawLibItem -> ChipName,
  1370.              &DrawLibItem -> ChipNameOrient,
  1371.              1,
  1372.              &DrawLibItem -> ChipNameX,
  1373.              &DrawLibItem -> ChipNameY,
  1374.                          PopPosition)) {
  1375.         EEActiveWindow -> EEDrawList =       /* Remove from global list. */
  1376.                 EEActiveWindow -> EEDrawList -> Pnext;
  1377.         DrawLibPart(DrawLibItem, GR_COPY_PUT, 0);
  1378.         MyFree((VoidPtr) DrawLibItem -> ChipName);
  1379.         MyFree((VoidPtr) DrawLibItem);
  1380.         return NULL;
  1381.     }
  1382.     }
  1383.  
  1384.     DrawLibPart(DrawLibItem, GR_COPY_PUT, 1);
  1385.  
  1386.     strcpy(Line, Entry -> Prefix);
  1387.  
  1388.     Cursor.CursorType = INTR_CURSOR_ARROW;
  1389.  
  1390.     if (strlen(Entry -> Prefix) > 0 &&
  1391.     IntrQueryYesNo("Display part name?", EEPopUpFrameColor,
  1392.                        EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  1393.                        EEWindowsFrameWidth, &Cursor, PopPosition) &&
  1394.     strlen(IntrQueryLine("Part name:", Line, LINE_LEN - 1,
  1395.                      EEPopUpFrameColor, EEPopUpBackColor,
  1396.                              EEPopUpForeColor, EEWindowsFrameWidth,
  1397.                              PopPosition)) > 0) {
  1398.     
  1399.     /* DrawLibItem -> PartName = strdup(Line); */
  1400.  
  1401. if (Entry -> NumOfUnits > 1 & EESubName == TRUE) 
  1402.     sprintf(L2,"%s (%d)",Line,Multi);
  1403. else
  1404.     sprintf(L2,"%s",Line);
  1405.     DrawLibItem -> PartName = strdup(L2);
  1406.  
  1407.     DrawLibItem -> PartNameX = DrawLibItem -> PosX;
  1408.     DrawLibItem -> PartNameY = DrawLibItem -> PosY;
  1409.     if (!PlaceString(DrawLibItem -> PartName,
  1410.              &DrawLibItem -> PartNameOrient,
  1411.              1,
  1412.              &DrawLibItem -> PartNameX,
  1413.              &DrawLibItem -> PartNameY,
  1414.                          PopPosition)) {
  1415.         if (DrawLibItem -> ChipName)
  1416.         MyFree((VoidPtr) DrawLibItem -> ChipName);
  1417.         EEActiveWindow -> EEDrawList =     /* Remove from global list. */
  1418.                 EEActiveWindow -> EEDrawList -> Pnext;
  1419.         DrawLibPart(DrawLibItem, GR_COPY_PUT, 0);
  1420.         MyFree((VoidPtr) DrawLibItem -> PartName);
  1421.         MyFree((VoidPtr) DrawLibItem);
  1422.         return NULL;
  1423.     }
  1424.     }
  1425.  
  1426.     DrawLibPart(DrawLibItem, GR_COPY_PUT, 1);
  1427.  
  1428.     EEActiveWindow -> EEDrawList =
  1429.         EEActiveWindow -> EEDrawList -> Pnext;   /* Remove from global list. */
  1430.     DrawLibItem -> Pnext = NULL;
  1431.  
  1432.     return (DrawGenericStruct *) DrawLibItem;
  1433. }
  1434.  
  1435. /*****************************************************************************
  1436. * Routine to reposition a library item.                         *
  1437. *****************************************************************************/
  1438. BooleanType RePosLibItem(DrawLibItemStruct *DrawLibItem, int PopPosition)
  1439. {
  1440.     BooleanType Transform,
  1441.     RetVal = FALSE;
  1442.     int TempR, *TransMat[2], TempMat[2][2];
  1443.  
  1444.     /* Prepare the transformation information: */
  1445.     TransMat[0] = DrawLibItem -> Transform[0];
  1446.     TransMat[1] = DrawLibItem -> Transform[1];
  1447.  
  1448.     Cursor.CursorType = INTR_CURSOR_ARROW;
  1449.  
  1450.     if (TransPopUpMenu == NULL) TransPopUpMenu =
  1451.         IntrPopUpMenuCreate("Transform", (char **) TransformStrs, 0,
  1452.                     TRANS_MENU_SIZE, EEPopUpFrameColor,
  1453.                             EEPopUpBackColor, EEPopUpForeColor,
  1454.                             EEPopUpXorColor, EEWindowsFrameWidth, &Cursor);
  1455.  
  1456.     while (TRUE) {
  1457.     if (!IntrPopUpMenu(TransPopUpMenu, PopPosition))
  1458.         return RetVal;
  1459.  
  1460.         Transform = TRUE;
  1461.     switch (TransPopUpMenu -> SelectedIndex) {
  1462.         case 0:
  1463.         return RetVal;
  1464.         case 2:
  1465.         TempMat[0][0] = TempMat[1][1] = 0.0;
  1466.         TempMat[0][1] = 1.0;
  1467.         TempMat[1][0] = -1.0;
  1468.         break;
  1469.         case 3:
  1470.         TempMat[0][0] = TempMat[1][1] = 0.0;
  1471.         TempMat[0][1] = -1.0;
  1472.         TempMat[1][0] = 1.0;
  1473.         break;
  1474.         case 4:
  1475.         TempMat[0][0] = 1.0;
  1476.         TempMat[1][1] = -1.0;
  1477.         TempMat[0][1] = TempMat[1][0] = 0.0;
  1478.         break;
  1479.         case 5:
  1480.         TempMat[0][0] = -1.0;
  1481.         TempMat[1][1] = 1.0;
  1482.         TempMat[0][1] = TempMat[1][0] = 0.0;
  1483.         break;
  1484.         default:
  1485.         Transform = FALSE;
  1486.         break;
  1487.     }
  1488.     if (Transform) {
  1489.         DrawLibPart(DrawLibItem, GR_COPY_PUT, 0);
  1490.  
  1491.         TempR = TransMat[0][0] * TempMat[0][0] +
  1492.                         TransMat[0][1] * TempMat[1][0];
  1493.         TransMat[0][1] = TransMat[0][0] * TempMat[0][1] +
  1494.                         TransMat[0][1] * TempMat[1][1];
  1495.         TransMat[0][0] = TempR;
  1496.         TempR = TransMat[1][0] * TempMat[0][0] +
  1497.                         TransMat[1][1] * TempMat[1][0];
  1498.         TransMat[1][1] = TransMat[1][0] * TempMat[0][1] +
  1499.                         TransMat[1][1] * TempMat[1][1];
  1500.         TransMat[1][0] = TempR;
  1501.  
  1502.         DrawLibPart(DrawLibItem, GR_COPY_PUT, 1);
  1503.  
  1504.             RetVal = TRUE;
  1505.     }
  1506.     }
  1507. }
  1508.  
  1509. /*****************************************************************************
  1510. * Routine to place a library item. Return FALSE if ABORT signaled.         *
  1511. *****************************************************************************/
  1512. BooleanType PlaceLibItem(DrawLibItemStruct *DrawLibItem)
  1513. {
  1514.     int Event, NewPosX, NewPosY, OldPosX, OldPosY, Dx, Dy;
  1515.     char Line[LINE_LEN_SHORT];
  1516.     LibraryEntryStruct *Entry;
  1517.  
  1518.     Cursor.CursorType = INTR_CURSOR_ARROW;
  1519.  
  1520.     if ((Entry = FindLibPart(DrawLibItem -> ChipName)) == NULL) {
  1521.     sprintf(Line, "Failed to find part \"%s\" in library",
  1522.                         DrawLibItem -> ChipName);
  1523.     IntrQueryContinue(Line, EEPopUpFrameColor,
  1524.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  1525.                           EEWindowsFrameWidth, &Cursor, INTR_WNDW_PLACE_CENTER);
  1526.     return FALSE;
  1527.     }
  1528.     IntrPushCursorType();
  1529.     Cursor.CursorType = INTR_CURSOR_CUSTOM;
  1530.     Cursor.CursorRoutine = DrawingEntryCursor;
  1531.     IntrSetCursorType(&Cursor);
  1532.  
  1533.     CrsrDrawLibItem = DrawLibItem;
  1534.     CrsrLibEntry = Entry;
  1535.     if (DrawLibItem -> PosX == -20000) {        /* First time placement. */
  1536.     DrawLibItem -> PosX = EE_SNAP(GRInvMapX((EEActiveBBox -> Xmin +
  1537.                          EEActiveBBox -> Xmax) / 2));
  1538.     DrawLibItem -> PosY = EE_SNAP(GRInvMapY((EEActiveBBox -> Ymin +
  1539.                          EEActiveBBox -> Ymax) / 2));
  1540.     }
  1541.     GRCurrentCursorX = GRMapX(DrawLibItem -> PosX);
  1542.     GRCurrentCursorY = GRMapY(DrawLibItem -> PosY);
  1543.     sprintf(Line, "Place part \"%s\"", DrawLibItem -> ChipName);
  1544.     IntrDrawMessage(Line, EEPopUpForeColor, EEPopUpBackColor);
  1545.  
  1546.     OldPosX = DrawLibItem -> PosX;
  1547.     OldPosY = DrawLibItem -> PosY;
  1548.  
  1549.     if ((Event = IntrGetEventWaitSA(&NewPosX, &NewPosY)) == INTR_EVNT_SELECT) {
  1550.         DrawLibItem -> PosX = GRInvMapX(NewPosX);
  1551.     DrawLibItem -> PosY = GRInvMapY(NewPosY);
  1552.     DrawLibItem -> PosX = EE_SNAP(DrawLibItem -> PosX);
  1553.     DrawLibItem -> PosY = EE_SNAP(DrawLibItem -> PosY);
  1554.     Dx = DrawLibItem -> PosX - OldPosX;
  1555.     Dy = DrawLibItem -> PosY - OldPosY;
  1556.     DrawLibItem -> PartNameX += Dx;
  1557.     DrawLibItem -> PartNameY += Dy;
  1558.     DrawLibItem -> ChipNameX += Dx;
  1559.     DrawLibItem -> ChipNameY += Dy;
  1560.     DrawLibItem -> BBoxMinX += Dx;
  1561.     DrawLibItem -> BBoxMinY += Dy;
  1562.     DrawLibItem -> BBoxMaxX += Dx;
  1563.     DrawLibItem -> BBoxMaxY += Dy;
  1564.     }
  1565.  
  1566.     IntrEraseMessage();
  1567.  
  1568.     IntrPopCursorType();
  1569.     Cursor.CursorType = INTR_CURSOR_ARROW;
  1570.  
  1571.     return Event != INTR_EVNT_ABORT;
  1572. }
  1573.  
  1574. /*****************************************************************************
  1575. * Routine to display an outline version of given library entry.             *
  1576. * This routine is applied by the LibCreateNewpart routine above.         *
  1577. *****************************************************************************/
  1578. static void DrawingEntryCursor(int PartX, int PartY)
  1579. {
  1580.     int i, x1, y1, x2, y2, PinWidth,
  1581.     y, MapX1, MapY1, MapX2, MapY2, TransMat[2][2],
  1582.         LastColor = GRGetColor();
  1583.     LibraryDrawEntryStruct *DEntry;
  1584.  
  1585.     /* Map from screen coords. to drawing coords. and offset as required. */
  1586.     GRSetColor(EE_HIGHLIGHT_COLOR);
  1587.  
  1588.     PartX = GRInvMapX(PartX);
  1589.     PartY = GRInvMapY(PartY);
  1590.  
  1591.     GEN_COPY(TransMat, CrsrDrawLibItem -> Transform, sizeof(int) * 4);
  1592.  
  1593.     if (CrsrLibEntry -> Drawings != NULL) {
  1594.     DEntry = CrsrLibEntry -> Drawings;
  1595.     while (DEntry != NULL) {
  1596.         switch (DEntry -> DrawType) {
  1597.         case ARC_DRAW_TYPE:
  1598.         case CIRCLE_DRAW_TYPE:
  1599.         case TEXT_DRAW_TYPE:
  1600.             break;
  1601.         case SQUARE_DRAW_TYPE:
  1602.             x1 = PartX + TransMat[0][0] * DEntry -> U.Sqr.x1
  1603.                    + TransMat[0][1] * DEntry -> U.Sqr.y1;
  1604.             y1 = PartY + TransMat[1][0] * DEntry -> U.Sqr.x1
  1605.                    + TransMat[1][1] * DEntry -> U.Sqr.y1;
  1606.             x2 = PartX + TransMat[0][0] * DEntry -> U.Sqr.x2
  1607.                    + TransMat[0][1] * DEntry -> U.Sqr.y2;
  1608.             y2 = PartY + TransMat[1][0] * DEntry -> U.Sqr.x2
  1609.                    + TransMat[1][1] * DEntry -> U.Sqr.y2;
  1610.             GRMoveTo(x1, y1);
  1611.             GRLineTo(x1, y2);
  1612.             GRLineTo(x2, y2);
  1613.             GRLineTo(x2, y1);
  1614.             GRLineTo(x1, y1);
  1615.             break;
  1616.         case LINE_DRAW_TYPE:
  1617.             GRMoveTo(x1 = PartX + TransMat[0][0] * DEntry -> U.Line.x1
  1618.                     + TransMat[0][1] * DEntry -> U.Line.y1,
  1619.                  y1 = PartY + TransMat[1][0] * DEntry -> U.Line.x1
  1620.                     + TransMat[1][1] * DEntry -> U.Line.y1);
  1621.             GRLineTo(x2 = PartX + TransMat[0][0] * DEntry -> U.Line.x2
  1622.                     + TransMat[0][1] * DEntry -> U.Line.y2,
  1623.                  y2 = PartY + TransMat[1][0] * DEntry -> U.Line.x2
  1624.                     + TransMat[1][1] * DEntry -> U.Line.y2);
  1625.             break;
  1626.         case POLYLINE_DRAW_TYPE:
  1627.             GRMoveTo(PartX +
  1628.             TransMat[0][0] * DEntry -> U.Poly.PolyList[0] +
  1629.             TransMat[0][1] * DEntry -> U.Poly.PolyList[1],
  1630.                  PartY +
  1631.             TransMat[1][0] * DEntry -> U.Poly.PolyList[0] +
  1632.             TransMat[1][1] * DEntry -> U.Poly.PolyList[1]);
  1633.             for (i = 1; i < DEntry -> U.Poly.n; i++)
  1634.             GRLineTo(PartX +
  1635.                 TransMat[0][0] * DEntry -> U.Poly.PolyList[i * 2] +
  1636.                 TransMat[0][1] * DEntry -> U.Poly.PolyList[i * 2 + 1],
  1637.                  PartY +
  1638.                 TransMat[1][0] * DEntry -> U.Poly.PolyList[i * 2] +
  1639.                 TransMat[1][1] * DEntry -> U.Poly.PolyList[i * 2 + 1]);
  1640.             break;
  1641.         }
  1642.         DEntry = DEntry -> Pnext;
  1643.     }
  1644.     }
  1645.     else {          /* NULL Drawing - draw simple a box with all pins: */
  1646.     y1 = CrsrLibEntry -> TextInside ?
  1647.         PIN_WIDTH * CrsrLibEntry -> NumOfPins / 4 :
  1648.         PIN_WIDTH * CrsrLibEntry -> NumOfPins / 2;
  1649.     x1 = CrsrLibEntry -> TextInside ? (int) (y1 * CHIP_BOX_ASPECT_TI) :
  1650.                       (int) (y1 * CHIP_BOX_ASPECT_TO);
  1651.         /* But make sure we can still print somethings inside... */
  1652.     if (x1 < DRAW_TEXT_WIDTH * 12) x1 = DRAW_TEXT_WIDTH * 12;
  1653.     x2 = x1 / 2;
  1654.     y2 = y1 / 2;
  1655.     x1 = -x2;
  1656.     y1 = -y2;
  1657.     PinWidth = CrsrLibEntry -> TextInside ? PIN_WIDTH / 2 : PIN_WIDTH;
  1658.  
  1659.     GRMoveTo(PartX + TransMat[0][0] * x1 + TransMat[0][1] * y1,
  1660.          PartY + TransMat[1][0] * x1 + TransMat[1][1] * y1);
  1661.     GRLineTo(PartX + TransMat[0][0] * x1 + TransMat[0][1] * y2,
  1662.          PartY + TransMat[1][0] * x1 + TransMat[1][1] * y2);
  1663.     GRLineTo(PartX + TransMat[0][0] * x2 + TransMat[0][1] * y2,
  1664.          PartY + TransMat[1][0] * x2 + TransMat[1][1] * y2);
  1665.     GRLineTo(PartX + TransMat[0][0] * x2 + TransMat[0][1] * y1,
  1666.          PartY + TransMat[1][0] * x2 + TransMat[1][1] * y1);
  1667.     GRLineTo(PartX + TransMat[0][0] * x1 + TransMat[0][1] * y1,
  1668.          PartY + TransMat[1][0] * x1 + TransMat[1][1] * y1);
  1669.     for (i = 0; i < CrsrLibEntry -> NumOfPins / 2; i++) {
  1670.         y = y2 - PinWidth / 2 - i * PinWidth;
  1671.         MapX1 = PartX + TransMat[0][0] * x1 + TransMat[0][1] * y;
  1672.         MapY1 = PartY + TransMat[1][0] * x1 + TransMat[1][1] * y;
  1673.         MapX2 = PartX + TransMat[0][0] * (x1 - PIN_LENGTH) + TransMat[0][1] * y;
  1674.         MapY2 = PartY + TransMat[1][0] * (x1 - PIN_LENGTH) + TransMat[1][1] * y;
  1675.         GRMoveTo(MapX1, MapY1);
  1676.         GRLineTo(MapX2, MapY2);
  1677.     }
  1678.     for (i = CrsrLibEntry -> NumOfPins / 2 + 1;
  1679.          i <= CrsrLibEntry -> NumOfPins;
  1680.          i++) {
  1681.         y = y1 + PinWidth / 2 + (i - CrsrLibEntry -> NumOfPins / 2 - 1) *
  1682.                                 PinWidth;
  1683.         MapX1 = PartX + TransMat[0][0] * x2 + TransMat[0][1] * y;
  1684.         MapY1 = PartY + TransMat[1][0] * x2 + TransMat[1][1] * y;
  1685.         MapX2 = PartX + TransMat[0][0] * (x2 + PIN_LENGTH) + TransMat[0][1] * y;
  1686.         MapY2 = PartY + TransMat[1][0] * (x2 + PIN_LENGTH) + TransMat[1][1] * y;
  1687.         GRMoveTo(MapX1, MapY1);
  1688.         GRLineTo(MapX2, MapY2);
  1689.     }
  1690.     }
  1691.     GRSetColor(LastColor);
  1692. }
  1693.  
  1694. /*****************************************************************************
  1695. * Returns TRUE iff the given library item chip name is drawable.         *
  1696. *****************************************************************************/
  1697. BooleanType CanDrawChipName(char *LibName)
  1698. {
  1699.     char Line[LINE_LEN_SHORT];
  1700.     LibraryEntryStruct *Entry;
  1701.  
  1702.     if ((Entry = FindLibPart(LibName)) == NULL) {
  1703.     sprintf(Line, "Failed to find part \"%s\" in library", LibName);
  1704.         IntrQueryContinue(Line, EEPopUpFrameColor,
  1705.                   EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  1706.                           EEWindowsFrameWidth, &Cursor, INTR_WNDW_PLACE_CENTER);
  1707.     return FALSE;
  1708.     }
  1709.     return Entry -> DrawName;
  1710. }
  1711.